using System;
using System.Web;
using System.Net.Mail;

/// <summary>
/// Summary description for MailManager
/// </summary>
/// 
namespace CE.Mail
{
    public class MyMailManager
    {
        #region Private Variable
        private MailMessage mail = null;
        private MailAddress mailAddress = null;
        private SmtpClient mailClient = null;
        private int clientPort = -1;
        private string clientHost = String.Empty;
        private bool isEnabledSsl = false;
        private int mailType = -1;
        private string mailBody = "";
        private MailPriority mailPriority = MailPriority.Normal;


        static string smtphost = string.Empty;
        static string smtpport = string.Empty;
        static string smtpaccount = string.Empty;
        static string smtpauthcode = string.Empty;
        static bool smtpenablessl = false;
        static string smtpreplytoemail = string.Empty;
        static string smtpdisplyname = string.Empty;

        #endregion

        public MyMailManager()
        {
            mailClient = new SmtpClient();
            mailClient.Host = "smtp.gmail.com";
            mailClient.Port = 587;
            mailClient.EnableSsl = true;
        }

        public MyMailManager(string HostName, string Port, bool EnableSSL, string Account, string AuthCode)
        {
            smtphost = HostName;
            smtpenablessl = EnableSSL;
            smtpport = Port;
            smtpaccount = Account;
            smtpauthcode = AuthCode;
        }

        public static bool SendGGMail(string SMTPAccount, string SMTPAuthCode, string EmailAddress, string CCEmail, string BCCEmail, string EmailSubject, string EmailMessage, string ReplyToMail)
        {
            string mailBody = EmailMessage;

            smtphost = System.Configuration.ConfigurationManager.AppSettings["SMTPHostName"].ToString();
            smtpport = System.Configuration.ConfigurationManager.AppSettings["SMTPPort"].ToString();
            smtpaccount = SMTPAccount;
            smtpauthcode = SMTPAuthCode;
            smtpenablessl = Convert.ToBoolean(System.Configuration.ConfigurationManager.AppSettings["SMTPSslEnable"].ToString());
            //smtpreplytoemail = System.Configuration.ConfigurationManager.AppSettings["SMTPReplyTo");
            smtpreplytoemail = ReplyToMail;
            smtpdisplyname = System.Configuration.ConfigurationManager.AppSettings["SMTPDisplayName"].ToString();

            string IsLive = System.Configuration.ConfigurationManager.AppSettings["IsOnLive"].ToString();
            if (IsLive == "0" || IsLive == "2")
            {
                EmailSubject = "[TS] " + EmailSubject;
            }

            bool _result = SendMailNew(smtphost,
                        Convert.ToInt32(smtpport),
                        smtpaccount,
                        smtpauthcode,
                        smtpdisplyname,
                        smtpaccount,
                        "Mail Service",
                        EmailAddress,
                        CCEmail,
                        BCCEmail,
                        smtpreplytoemail,
                        EmailSubject,
                        mailBody,
                        smtpenablessl);
            return _result;
        }

        public static bool SendMailNew(string sHost, int nPort, string sUserName, string sPassword, string sFromName, string sFromEmail,
        string sToName, string sToEmail, string sCCEmail, string sBCCEmail, string sReplyToEmail, string sHeader, string sMessage, bool fSSL)
        {
            if (sToName.Length == 0)
                sToName = sToEmail;
            if (sFromName.Length == 0)
                sFromName = sFromEmail;

            try
            {
                MailMessage Mail = new MailMessage();

                if (sToEmail != "")
                {
                    string[] sGetToEmails = sToEmail.Split(';');

                    foreach (string toemail in sGetToEmails)
                    {
                        if (toemail != "")
                            Mail.To.Add(new MailAddress(toemail));
                    }
                }

                if (sCCEmail != "")
                {
                    string[] sGetCCEmails = sCCEmail.Split(';');

                    foreach (string ccemail in sGetCCEmails)
                    {
                        if (ccemail != "")
                            Mail.CC.Add(new MailAddress(ccemail));
                    }
                }

                if (sBCCEmail != "")
                {
                    string[] sGetBCCEmails = sBCCEmail.Split(';');

                    foreach (string bccemail in sGetBCCEmails)
                    {
                        if (bccemail != "")
                            Mail.Bcc.Add(new MailAddress(bccemail));
                    }

                }

                Mail.From = new MailAddress(sFromEmail, sFromName);
                Mail.Subject = sHeader;
                Mail.Body = sMessage;
                Mail.IsBodyHtml = true;
                Mail.ReplyTo = new MailAddress(sReplyToEmail);

                SmtpClient smtp = new SmtpClient();
                smtp.Timeout = 300000;
                smtp.Port = nPort;
                smtp.Host = sHost;
                smtp.Credentials = new System.Net.NetworkCredential(sUserName, sPassword);

                if (fSSL)
                {
                    smtp.EnableSsl = true;
                }

                //object userState = Mail;

                //smtp.SendCompleted += new SendCompletedEventHandler(MailDeliveryComplete);
                //smtp.SendAsync(Mail, userState);
                smtp.Send(Mail);

            }
            catch (SmtpException Ex)
            {
                string _emailSetting = "Host : " + sHost + " From Email : " + sUserName + " To Email : " + sToEmail + " Subject : " + sHeader;
                CreateSMTPExceptionLog(Ex, _emailSetting, "SendMailNew SMTP Exception ");
            }
            catch (Exception Ex)
            {
                string _emailSetting = "Host : " + sHost + " From Email : " + sUserName + " To Email : " + sToEmail + " Subject : " + sHeader;
                CreateExceptionLog(Ex, _emailSetting, "SendMailNew Exception");

                return false;
            }
            return true;
        }

        public static DateTime GetUTCDateTime()
        {
            DateTime _CurrentDateTime = DateTime.UtcNow.AddHours(7);
            return _CurrentDateTime;
        }

        private static void CreateSMTPExceptionLog(SmtpException Ex, string EmailSettingInfo, string strLocation)
        {
            String[] _fileContent = new String[9];
            _fileContent[0] = "Email Setting : " + EmailSettingInfo;
            _fileContent[1] = "Source : " + Ex.Source;
            _fileContent[2] = "Date Time : " + GetUTCDateTime().ToString();
            _fileContent[3] = "Stack Trace :" + Ex.StackTrace.ToString();
            _fileContent[4] = "Target Site : " + Ex.TargetSite.ToString();
            _fileContent[5] = "Location : " + "MyMailManager - " + strLocation;
            _fileContent[6] = "Status Code : " + Ex.StatusCode.ToString();
            _fileContent[8] = "Message : " + Ex.Message;
            _fileContent[7] = "Help Link : " + Ex.HelpLink;

            WriteExceptionLog("MailSMTP_", _fileContent);
        }

        static void MailDeliveryComplete(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            //Console.WriteLine("Message \"{0}\".", e.UserState);

            if (e.Error != null)
            {
                try
                {
                    //Get the Original MailMessage object
                    MailMessage mail = (MailMessage)e.UserState;

                    //write out the subject
                    string subject = mail.Subject;

                    System.Text.StringBuilder errorMsg = new System.Text.StringBuilder();
                    errorMsg.Append(string.Format("An error occurred sending message [{0}]. {1}", e.UserState.ToString(), e.Error.Message));

                    if (e.Error.InnerException != null)
                        errorMsg.Append(Environment.NewLine + "Inner exception message: " + e.Error.InnerException.Message);

                    errorMsg.Append(Environment.NewLine + "Subject: " + subject);
                    errorMsg.Append(Environment.NewLine + "Sender: " + mail.Sender.Address.ToString());
                    errorMsg.Append(Environment.NewLine + "Sender Host: " + mail.Sender.Host.ToString());
                    errorMsg.Append(Environment.NewLine + "From : " + mail.From.Address.ToString());
                    errorMsg.Append(Environment.NewLine + "From Host : " + mail.From.Host.ToString());
                    string _toAddresses = "";
                    foreach (MailAddress _msgMail in mail.To)
                    {
                        _toAddresses += _msgMail.Address.ToString() + ";";
                    }
                    errorMsg.Append(Environment.NewLine + "To : " + _toAddresses);
                    CreateMailDeliveryExceptionLog("SendMailNew MailDeliveryComplete Exception", errorMsg);
                }
                catch (Exception Ex)
                {
                    Ex = null;
                }
            }
            else if (e.Cancelled)
            {
                //Console.WriteLine("Sending of email cancelled.");
            }
            else
            {
                //Console.WriteLine("Message sent.");
            }
        }

        public static bool SendMailNewByAttachments(string sHost, int nPort, string sUserName, string sPassword, string sFromName, string sFromEmail,
        string sToName, string sToEmail, string sCCEmail, string sBCCEmail, string sReplyToEmail, string sHeader, string sMessage, bool fSSL, string[] fileList)
        {
            if (sToName.Length == 0)
                sToName = sToEmail;
            if (sFromName.Length == 0)
                sFromName = sFromEmail;

            try
            {
                MailMessage Mail = new MailMessage();

                if (sToEmail != "")
                {
                    string[] sGetToEmails = sToEmail.Split(';');

                    foreach (string toemail in sGetToEmails)
                    {
                        if (toemail != "")
                            Mail.To.Add(new MailAddress(toemail));
                    }
                }

                if (sCCEmail != "")
                {
                    string[] sGetCCEmails = sCCEmail.Split(';');

                    foreach (string ccemail in sGetCCEmails)
                    {
                        if (ccemail != "")
                            Mail.CC.Add(new MailAddress(ccemail));
                    }
                }

                if (sBCCEmail != "")
                {
                    string[] sGetBCCEmails = sBCCEmail.Split(';');

                    foreach (string bccemail in sGetBCCEmails)
                    {
                        if (bccemail != "")
                            Mail.Bcc.Add(new MailAddress(bccemail));
                    }

                }

                Mail.From = new MailAddress(sFromEmail, sFromName);
                Mail.Subject = sHeader;
                Mail.Body = sMessage;
                Mail.IsBodyHtml = true;
                Mail.ReplyTo = new MailAddress(sReplyToEmail);

                SmtpClient smtp = new SmtpClient();
                smtp.Timeout = 300000;
                smtp.Port = nPort;
                smtp.Host = sHost;
                smtp.Credentials = new System.Net.NetworkCredential(sUserName, sPassword);

                if (fSSL)
                {
                    smtp.EnableSsl = true;
                }

                object userState = Mail;

                for (int i = 0; i < fileList.Length; i++)
                {
                    Mail.Attachments.Add(new Attachment(fileList[i].ToString()));

                    //An Int32 that specifies the time-out value in milliseconds. 
                    //The default value is 100,000 (100 seconds).
                    smtp.Timeout += 240000;
                }

                smtp.SendCompleted += new SendCompletedEventHandler(MailDeliveryComplete);
                //smtp.SendAsync(Mail, userState);
                smtp.Send(Mail);

            }
            catch (Exception Ex)
            {
                string _emailSetting = "Host : " + sHost + " From Email : " + sUserName + " To Email : " + sToEmail + " Subject : " + sHeader;
                CreateExceptionLog(Ex, _emailSetting, "SendMailNew By Attachments Exception");

                return false;
            }
            return true;
        }

        private static void CreateExceptionLog(Exception Ex, string EmailSettingInfo, string strLocation)
        {
            String[] _fileContent = new String[7];
            _fileContent[0] = "Email Setting : " + EmailSettingInfo;
            _fileContent[1] = "Source : " + Ex.Source;
            _fileContent[2] = "Date Time : " + GetUTCDateTime().ToString();
            _fileContent[3] = "Stack Trace :" + Ex.StackTrace.ToString();
            _fileContent[4] = "Target Site : " + Ex.TargetSite.ToString();
            _fileContent[5] = "Location : " + "MyMailManager - " + strLocation;
            _fileContent[6] = "Message : " + Ex.Message;

            WriteExceptionLog("Mail_", _fileContent);
        }

        private static void WriteExceptionLog(string strPrefixFileName, string[] strException)
        {
            try
            {
                CE.InputOut.MyIO _newFile = new CE.InputOut.MyIO();
                string _filePath = AppDomain.CurrentDomain.BaseDirectory + "Exception\\";
                if (_newFile.CheckDirectory(_filePath))
                {
                    string _curMonth = GetUTCDateTime().Year.ToString("0000") + GetUTCDateTime().Month.ToString("00");

                    if (!_newFile.CheckDirectory(_filePath + _curMonth))
                    {
                        if (_newFile.CreateDirectory(_filePath, _curMonth))
                        {
                            _filePath += _curMonth + "\\";
                        }
                    }
                    else
                    {
                        _filePath += _curMonth + "\\";
                    }

                    string _fileName = strPrefixFileName + _curMonth + GetUTCDateTime().Day.ToString("00") + GetUTCDateTime().Second.ToString("00") + GetUTCDateTime().Millisecond.ToString("00") + ".txt";

                    _newFile.WriteNewFile(_filePath, _fileName, strException);
                    _newFile = null;
                }
            }
            catch (Exception Ex)
            {
                Ex = null;
            }
        }

        private static void CreateMailDeliveryExceptionLog(string strLocation, System.Text.StringBuilder ErrorMessage)
        {
            String[] _fileContent = new String[3];
            _fileContent[0] = "Date Time : " + GetUTCDateTime().ToString();
            _fileContent[1] = "Location : " + "MyMailManager - " + strLocation;
            _fileContent[2] = "Message : " + ErrorMessage;

            WriteMailDeliveryExceptionLog("MailDelivery_", _fileContent);
        }

        private static void WriteMailDeliveryExceptionLog(string strPrefixFileName, string[] strException)
        {
            try
            {
                CE.InputOut.MyIO _newFile = new CE.InputOut.MyIO();
                string _filePath = AppDomain.CurrentDomain.BaseDirectory + "Exception\\";
                if (_newFile.CheckDirectory(_filePath))
                {
                    string _curMonth = GetUTCDateTime().Year.ToString("0000") + GetUTCDateTime().Month.ToString("00");

                    if (!_newFile.CheckDirectory(_filePath + _curMonth))
                    {
                        if (_newFile.CreateDirectory(_filePath, _curMonth))
                        {
                            _filePath += _curMonth + "\\";
                        }
                    }
                    else
                    {
                        _filePath += _curMonth + "\\";
                    }

                    string _fileName = strPrefixFileName + _curMonth + GetUTCDateTime().Day.ToString("00") + GetUTCDateTime().Second.ToString("00") + GetUTCDateTime().Millisecond.ToString("00") + ".txt";

                    _newFile.WriteNewFile(_filePath, _fileName, strException);
                    _newFile = null;
                }
            }
            catch (Exception Ex)
            {
                Ex = null;
            }
        }
    }
}
